package sys_serv

import (
	"strconv"
	"strings"
	"ubt-aio-service/app/mod/sys_mod"
	"ubt-aio-service/app/pkg/db"
	"ubt-aio-service/app/utils"
)

type sysRole struct{}

var SysRoleServ = sysRole{}

// Add 新增角色
func (s *sysRole) Add(req *sys_mod.SysRoleSaveReq) *utils.ResJson {
	sqlStr := `INSERT INTO sys_role(role_name, quan_pin, jian_pin, role_code, menu_codes, btn_codes, data_role, states, add_time, upd_time) 
		VALUES ($1, $2, $3, $4, $5, $6, $7, 1, EXTRACT(epoch FROM NOW()), EXTRACT(epoch FROM NOW()))`
	return db.CudData(sqlStr, req.RoleName, req.QuanPin, req.JianPin, req.RoleCode, req.MenuCodes, req.BtnCodes, req.DataRole)
}

// Exists 判断角色编码是否存在
func (s *sysRole) Exists(req *sys_mod.SysRoleExtVo) bool {
	sqlStr := "SELECT role_id FROM sys_role WHERE states=1 AND (role_code=$1 OR role_name=$2)"
	param := make([]any, 0)
	param = append(param, req.RoleCode)
	param = append(param, req.RoleName)
	if req.RoleId != "" {
		sqlStr += " AND role_id!=$3"
		param = append(param, req.RoleId)
	}
	if res := db.GetOne(sqlStr, param...); res.Code == utils.Succeed.Code {
		return true
	}
	return false
}

// Update 修改角色
func (s *sysRole) Update(req *sys_mod.SysRoleSaveReq) *utils.ResJson {
	sqlStr := "UPDATE sys_role SET role_name=$1, quan_pin=$2, jian_pin=$3, role_code=$4, menu_codes=$5, btn_codes=$6, data_role=$7, upd_time=EXTRACT(epoch FROM NOW()) WHERE role_id=$8"
	return db.CudData(sqlStr, req.RoleName, req.QuanPin, req.JianPin, req.RoleCode, req.MenuCodes, req.BtnCodes, req.DataRole, req.RoleId)
}

// Deletes 删除角色
func (s *sysRole) Deletes(req *sys_mod.SysRoleProReq) *utils.ResJson {
	var (
		param []any
		q     string
		n     = 0
	)
	idList := strings.Split(req.RoleIds, ",")
	for _, curId := range idList {
		n++
		q += "$" + strconv.Itoa(n) + ","
		param = append(param, curId)
	}
	q = q[:len(q)-1]
	sqlStr := "UPDATE sys_role SET states=2, upd_time=EXTRACT(epoch FROM NOW()) WHERE role_id IN (" + q + ")"
	return db.CudData(sqlStr, param...)
}

// One 获取角色详情
func (s *sysRole) One(roleId string) *utils.ResJson {
	sqlStr := "SELECT role_id, role_name, role_code, menu_codes, btn_codes, data_role, add_time, upd_time FROM sys_role WHERE role_id=$1"
	return db.GetOne(sqlStr, roleId)
}

// Count 获取角色数量
func (s *sysRole) Count(req *sys_mod.SysRolePageReq) *utils.ResJson {
	sqlStr := "SELECT COUNT(1) AS nums FROM sys_role WHERE states=1"
	var param []any
	var n = 0
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "role_name LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"role_code LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR " +
				"quan_pin LIKE '%'||$" + strconv.Itoa(n+3) + "||'%' OR " +
				"jian_pin LIKE '%'||$" + strconv.Itoa(n+4) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			n += 4
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.DataRole != 0 {
		n++
		sqlStr += " AND data_role=$" + strconv.Itoa(n)
		param = append(param, req.DataRole)
	}
	if res := db.GetOne(sqlStr, param...); res.Code == utils.Succeed.Code && res.Data.(map[string]any)["nums"].(int64) > 0 {
		return res
	}
	return utils.NoData
}

// Page 获取角色分页列表
func (s *sysRole) Page(req *sys_mod.SysRolePageReq) *utils.ResJson {
	sqlStr := "SELECT role_id, role_name, role_code, data_role, add_time FROM sys_role WHERE states=1"
	var param []any
	var n = 0
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "role_name LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"role_code LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR " +
				"quan_pin LIKE '%'||$" + strconv.Itoa(n+3) + "||'%' OR " +
				"jian_pin LIKE '%'||$" + strconv.Itoa(n+4) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			n += 4
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.DataRole != 0 {
		n++
		sqlStr += " AND data_role=$" + strconv.Itoa(n)
		param = append(param, req.DataRole)
	}
	sqlStr += " ORDER BY role_code LIMIT $" + strconv.Itoa(n+1) + " OFFSET $" + strconv.Itoa(n+2)
	param = append(param, req.Limit)
	param = append(param, req.Offset)
	return db.GetAll(sqlStr, param...)
}

// Select 获取角色下拉列表
func (s *sysRole) Select(req *sys_mod.SysRoleSelReq) *utils.ResJson {
	sqlStr := "SELECT role_id sel_id, role_name sel_name, role_code sel_code, false chked FROM sys_role WHERE states=1"
	param := make([]any, 0)
	var n = 0
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "role_name LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"role_code LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR " +
				"quan_pin LIKE '%'||$" + strconv.Itoa(n+3) + "||'%' OR " +
				"jian_pin LIKE '%'||$" + strconv.Itoa(n+4) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			n += 4
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	sqlStr += " ORDER BY role_code"
	return db.GetAll(sqlStr, param...)
}
